//
// Created by wyh on 2025-06-17 19:14.
//

#ifndef TEST_UTILITY_VECTOR_H
#define TEST_UTILITY_VECTOR_H

#include<iostream>

namespace wyh {
    namespace stl {
        template<typename T>
        class Vector
        {
        public:
            Vector();

            Vector(const Vector<T>& other);

            ~Vector();

            void push_back(const T &value);

            void show() const;

            void pop_back();

            T &at(int index);

            const T &at(int index) const;

            T &front();

            const T &front() const;

            T &back();

            const T &back() const;

            bool empty() const noexcept;

            bool clear() noexcept;

            int size() const noexcept;

            int capacity() const noexcept;

            T *data() noexcept;

            const T *data() const noexcept;

            T &operator[](int index);

            const T &operator[](int index) const;

            Vector<T> &operator=(const Vector<T> &other);

            void swap(Vector<T> &other);

            void resize(int n);

            void resize(int n, const T &value);

            void reserve(int n);

            class iterator
            {
            public:
                iterator() : m_pointer(nullptr)
                {}

                iterator(T *pointer) : m_pointer(pointer)
                {}

                ~iterator() = default;

                bool operator==(const iterator &other) const
                {
                    return m_pointer == other.m_pointer;
                }

                bool operator!=(const iterator &other) const
                {
                    return m_pointer != other.m_pointer;
                }

                iterator &operator=(const iterator &other)
                {
                    if(this==&other)
                        return *this;

                    m_pointer = other.m_pointer;
                    return *this;
                }

                //前缀++
                iterator &operator++()
                {
                    m_pointer += 1;
                    return *this;
                }

                //后缀++
                iterator operator++(int)
                {
                    iterator it = *this;
                    ++(*this);
                    return it;
                }

                iterator operator+(int i)
                {
                    iterator it = *this;
                    it.m_pointer += i;
                    return it;
                }

                iterator operator+=(int i)
                {
                    m_pointer += i;
                    return *this;
                }

                //前缀--
                iterator &operator--()
                {
                    m_pointer -= 1;
                    return *this;
                }

                //后缀--
                iterator operator--(int)
                {
                    iterator it = *this;
                    --(*this);
                    return it;
                }

                iterator operator-(int i)
                {
                    iterator it = *this;
                    it.m_pointer -= i;
                    return it;
                }

                iterator operator-=(int i)
                {
                    m_pointer -= i;
                    return *this;
                }

                int operator-(const iterator &other) const
                {
                    return m_pointer - other.m_pointer;
                }

                T &operator*()
                {
                    return *m_pointer;
                }

                T *operator->()
                {
                    return m_pointer;
                }

            private:
                T *m_pointer;

            };

            iterator begin() noexcept;

            iterator end() noexcept;

            class reverse_iterator
            {
            public:
                reverse_iterator() : m_pointer(nullptr)
                {}

                reverse_iterator(T *pointer) : m_pointer(pointer)
                {}

                ~reverse_iterator() = default;

                bool operator==(const reverse_iterator &other) const
                {
                    return m_pointer == other.m_pointer;
                }

                bool operator!=(const reverse_iterator &other) const
                {
                    return m_pointer != other.m_pointer;
                }

                reverse_iterator &operator=(const reverse_iterator &other)
                {
                    if(this==&other)
                        return *this;

                    m_pointer = other.m_pointer;
                    return *this;
                }

                //前缀++
                reverse_iterator &operator++()
                {
                    m_pointer -= 1;
                    return *this;
                }

                //后缀++
                reverse_iterator operator++(int)
                {
                    reverse_iterator it = *this;
                    ++(*this);
                    return it;
                }

                reverse_iterator operator+(int i)
                {
                    reverse_iterator it = *this;
                    it.m_pointer -= i;
                    return it;
                }

                reverse_iterator &operator+=(int i)
                {
                    m_pointer -= i;
                    return *this;
                }

                //前缀--
                reverse_iterator &operator--()
                {
                    m_pointer += 1;
                    return *this;
                }

                //后缀--
                reverse_iterator operator--(int)
                {
                    reverse_iterator it = *this;
                    ++(*this);
                    return it;
                }

                reverse_iterator operator-(int i)
                {
                    reverse_iterator it = *this;
                    it.m_pointer += i;
                    return it;
                }

                reverse_iterator &operator-=(int i)
                {
                    m_pointer += i;
                    return *this;
                }

                T &operator*()
                {
                    return *m_pointer;
                }

                T *operator->()
                {
                    return m_pointer;
                }

            private:
                T *m_pointer;
            };

            reverse_iterator rbegin() noexcept;

            reverse_iterator rend() noexcept;

            iterator insert(iterator pos, const T &value);

            iterator insert(iterator pos, int n, const T &value);

            iterator erase(iterator pos);

            iterator erase(iterator first, iterator last);

        private:
            bool is_basic_type();

        private:
            T *m_data;
            int m_size;
            int m_capacity;
        };

        template<typename T>
        bool Vector<T>::is_basic_type() {
            if(std::is_pointer<T>::value){
                return true;
            }

            return (typeid(T)== typeid(bool)||
                    typeid(T)== typeid(char)||
                    typeid(T)== typeid(unsigned char)||
                    typeid(T)== typeid(short)||
                    typeid(T)== typeid(unsigned short)||
                    typeid(T)== typeid(int)||
                    typeid(T)== typeid(unsigned int)||
                    typeid(T)== typeid(long)||
                    typeid(T)== typeid(unsigned long)||
                    typeid(T)== typeid(float)||
                    typeid(T)== typeid(double));
        }

        template<typename T>
        typename Vector<T>::iterator Vector<T>::erase(Vector::iterator first, Vector::iterator last)
        {
            int f = first -begin();//first对应的数组下标
            int l = last - begin();//last对应的数组下标
            int n = last - first;//删除的元素个数

            for (int i = 0; i < m_size - l; i++)
            {
                m_data[f + i] = m_data[l + i];
            }

            m_size-=n;
            return first;
        }

        template<typename T>
        typename Vector<T>::iterator Vector<T>::erase(Vector::iterator pos)
        {
            if (pos == end())
            {
                throw std::logic_error("out of range");
            }

            if (end() - pos == 1)
            {
                //删除最后一个元素，其他元素不需要移动
                m_size -= 1;
                return end();
            }

            int size = pos -begin();
            for (int i = size; i < m_size - 1; i++)
            {
                m_data[i] = m_data[i + 1];
            }
            m_size -= 1;
            return pos;
        }

        template<typename T>
        typename Vector<T>::iterator Vector<T>::insert(Vector::iterator pos, int n, const T &value)
        {
            int size = pos - begin();
            if (m_size + n < m_capacity)
            {
                //先把后面的元素 往后挪，避免覆盖
                for (int i = m_size; i > size; i--)
                {
                    m_data[i + n - 1] = m_data[i - 1];
                }

                //中间那部分
                for (int i = 0; i < n; i++)
                {
                    m_data[size + i] = value;
                }

                //前面那部分不用动
                m_size += n;
                return Vector<T>::iterator(m_data + size);
            }

            while (m_size + n > m_capacity)
            {
                if (m_capacity == 0)
                {
                    m_capacity = 1;
                }
                else
                {
                    m_capacity *= 2;
                }
            }

            T *data = new T[m_capacity];
            //前面一部分保持不变
            for (int i = 0; i < size; i++)
            {
                data[i] = m_data[i];
            }

            //中间插入的部分，用value来填充
            for (int i = 0; i < n; i++)
            {
                data[size+i]=value;
            }

            //后面那部分往后挪
            for (int i = size; i < m_size; i++)
            {
                data[i + n] = m_data[i];
            }

            if (m_data != nullptr)
            {
                delete[] m_data;
                m_data = nullptr;
            }

            m_data = data;
            m_size += n;
            return Vector<T>::iterator(m_data + size);
        }

        template<typename T>
        typename Vector<T>::iterator Vector<T>::insert(Vector::iterator pos, const T &value)
        {
            return insert(pos, 1, value);
        }

        template<typename T>
        typename Vector<T>::reverse_iterator Vector<T>::rend() noexcept
        {
            Vector<T>::reverse_iterator it(m_data - 1);
            return it;
        }

        template<typename T>
        typename Vector<T>::reverse_iterator Vector<T>::rbegin() noexcept
        {
            Vector<T>::reverse_iterator it(m_data + m_size - 1);
            return it;
        }


        template<typename T>
        typename Vector<T>::iterator Vector<T>::end() noexcept
        {
            Vector<T>::iterator it(m_data + m_size);
            return it;
        }

        template<typename T>
        typename Vector<T>::iterator Vector<T>::begin() noexcept
        {
            Vector<T>::iterator it(m_data);
            return it;
        }

        template<typename T>
        void Vector<T>::reserve(int n)
        {
            if (m_capacity >= n)
            {
                return;
            }

            while (m_capacity < n)
            {
                if (m_capacity == 0)
                {
                    m_capacity = 1;
                }
                else
                {
                    m_capacity *= 2;
                }
            }

            T *data = new T[m_capacity];
            for (int i = 0; i < m_size; i++)
            {
                data[i] = m_data[i];
            }

            if (m_data != nullptr)
            {
                delete[] m_data;
                m_data = nullptr;
            }

            m_data = data;
        }

        template<typename T>
        void Vector<T>::resize(int n, const T &value)
        {
            if (n < m_size)
            {
                m_size = n;
                return;
            }

            if (n <= m_capacity)
            {
                for (int i = m_size; i < n; i++)
                {
                    m_data[i] = value;
                }
                m_size = n;
                return;
            }

            while (m_capacity < n)
            {
                if (m_capacity == 0)
                {
                    m_capacity = 0;
                }
                else
                {
                    m_capacity *= 2;
                }
            }

            T *data = new T[m_capacity];
            for (int i = 0; i < m_size; i++)
            {
                data[i] = m_data[i];
            }
            for (int i = m_size; i < n; i++)
            {
                data[i] = value;
            }
            if (m_data != nullptr)
            {
                delete[] m_data;
                m_data = nullptr;
            }

            m_data = data;
            m_size = n;
        }

        template<typename T>
        void Vector<T>::resize(int n)
        {
            resize(n, T());
        }

        template<typename T>
        void Vector<T>::swap(Vector<T> &other)
        {
            T *data = other.m_data;
            int size = other.m_size;
            int capacity = other.m_capacity;

            other.m_data = m_data;
            other.m_size = m_size;
            other.m_data = m_data;

            m_data = data;
            m_size = size;
            m_capacity = capacity;
        }

        template<typename T>
        Vector<T> &Vector<T>::operator=(const Vector<T> &other)
        {
            if (this == &other)
                return *this;

            if (m_data == other.m_data)
                return *this;

            if (m_capacity < other.m_capacity)
            {
                if (m_data != nullptr)
                {
                    delete[] m_data;
                    m_data = nullptr;
                    m_size = 0;
                    m_capacity = 0;
                }

                while (m_capacity < other.m_capacity)
                {
                    if (m_capacity == 0)
                    {
                        m_capacity = 1;
                    }
                    else
                    {
                        m_capacity *= 2;
                    }
                }

                m_data = new T[m_capacity];
            }

            for (int i = 0; i < other.m_size; i++)
            {
                m_data[i] = other.m_data[i];
            }
            m_size = other.m_size;

            return *this;
        }

        template<typename T>
        const T &Vector<T>::operator[](int index) const
        {
            return at(index);
        }

        template<typename T>
        T &Vector<T>::operator[](int index)
        {
            return at(index);
        }

        template<typename T>
        const T *Vector<T>::data() const noexcept
        {
            return data();
        }

        template<typename T>
        T *Vector<T>::data() noexcept
        {
            return m_data;
        }

        template<typename T>
        int Vector<T>::capacity() const noexcept
        {
            return m_capacity;
        }

        template<typename T>
        int Vector<T>::size() const noexcept
        {
            return m_size;
        }

        template<typename T>
        bool Vector<T>::clear() noexcept
        {
            m_size = 0;
            return true;
        }

        template<typename T>
        bool Vector<T>::empty() const noexcept
        {
            return m_size == 0;
        }

        template<typename T>
        const T &Vector<T>::back() const
        {
            return back();
        }

        template<typename T>
        T &Vector<T>::back()
        {
            if (m_size <= 0)
            {
                throw std::logic_error("vector is empty");
            }
            return m_data[m_size - 1];
        }

        template<typename T>
        const T &Vector<T>::front() const
        {
            return front();
        }

        template<typename T>
        T &Vector<T>::front()
        {
            if (m_size <= 0)
            {
                throw std::logic_error("vector is empty");
            }
            return m_data[0];
        }

        template<typename T>
        const T &Vector<T>::at(int index) const
        {
            return at(index);
        }

        template<typename T>
        T &Vector<T>::at(int index)
        {
            if (index < 0 || index >= m_size)
            {
                throw std::logic_error("out of range");
            }
            return m_data[index];
        }

        template<typename T>
        void Vector<T>::pop_back()
        {
            if (m_size > 0)
            {
                m_size--;
            }
        }

        template<typename T>
        Vector<T>::Vector():m_data(nullptr), m_size(0), m_capacity(0)
        {

        }

        template<typename T>
        Vector<T>::Vector(const Vector<T> &other)
        {
            while (m_capacity < other.m_size)
            {
                if (m_capacity == 0)
                {
                    m_capacity = 1;
                }
                else
                {
                    m_capacity *= 2;
                }
            }

            m_data = new T[m_capacity];

            for (int i = 0; i < other.m_size; i++)
            {
                m_data[i] = other.m_data[i];
            }
            m_size = other.m_size;
        }


        template<typename T>
        Vector<T>::~Vector()
        {
            if (m_data != nullptr)
            {
                delete[] m_data;
                m_data = nullptr;
            }
            m_size = 0;
            m_capacity = 0;
        }

        template<typename T>
        void Vector<T>::push_back(const T &value)
        {
            if (m_size < m_capacity)
            {
                m_data[m_size] = value;
                m_size++;
                return;
            }

            if (m_capacity == 0)
            {
                m_capacity = 1;
            }
            else
            {
                m_capacity *= 2;
            }

            T *data = new T[m_capacity];
            if(is_basic_type()){
                memcpy(data,m_data,m_size*sizeof(T));
            }else{
                for (int i = 0; i < m_size; i++) {
                    data[i] = m_data[i];
                }
            }

            if (m_data != nullptr)
            {
                delete[] m_data;
                m_data = nullptr;
            }

            m_data = data;
            m_data[m_size] = value;
            m_size++;
        }

        template<typename T>
        void Vector<T>::show() const
        {
            std::cout << "size=" << m_size << ",capacity=" << m_capacity << std::endl;
            for (int i = 0; i < m_size; i++)
            {
                std::cout << m_data[i] << ",";
            }
            std::cout << std::endl;
        }

    } // namespace stl
} // namespace wyh

#endif //TEST_UTILITY_VECTOR_H
